﻿using System;
using RealidadeAumentada.Entidades;

namespace RealidadeAumentada.Servicos.Analise.Histograma
{
    public class LimiteKittler : ILimite
    {
        public int ObterLimite(EHistograma i_histogram)
        {
            int i;
            double min = Double.MaxValue;
            int th = 0;
            int da, sa, db, sb, pa, pb;
            double oa, ob;

            int[] hist = i_histogram.data;
            int n = i_histogram.length;
            da = pa = 0;
            int h;
            for (i = 0; i < n; i++)
            {
                h = hist[i];
                da += h * i;
                pa += h * i * i;
            }
            sa = i_histogram.total_of_data;
            db = 0;
            sb = 0;
            pb = 0;


            for (i = n - 1; i > 0; i--)
            {
                int hist_count = hist[i];
                int hist_val = hist_count * i;
                int hist_val2 = hist_val * i;
                da -= hist_val;
                sa -= hist_count;
                pa -= hist_val2;
                db += hist_val;
                sb += hist_count;
                pb += hist_val2;

                double wa = (double)sa / (sa + sb);
                double wb = (double)sb / (sa + sb);
                if (wa == 0 || wb == 0)
                {
                    continue;
                }

                oa = ob = 0;
                double ma = sa != 0 ? (double)da / sa : 0;
                oa = ((double)(pa + ma * ma * sa - 2 * ma * da)) / sa;

                double mb = sb != 0 ? (double)db / sb : 0;
                ob = ((double)(pb + mb * mb * sb - 2 * mb * db)) / sb;

                double kai = wa * Math.Log(oa / wa) + wb * Math.Log(ob / wb);
                if (kai > 0 && min > kai)
                {
                    min = kai;
                    th = i;
                }

            }
            return th;
        }
    }
}
